// OrbitGenerator.js
import * as THREE from 'three';

export class OrbitGenerator {
  constructor() {
    // 默认轨道颜色
    this.orbitColors = {
      leo: '#64b5f6', // 浅蓝色
      meo: '#ba68c8', // 紫色
      geo: '#ffd54f',  // 黄色
      sgo: '#ffd54f'  // 黄色
    };
    
    // 存储生成的轨道数据
    this.orbitPoints = {};
    this.orbitLines = {};
  }
  
  /**
   * 根据轨道参数生成轨道点集
   * @param {Object} orbitParams - 轨道参数对象
   * @param {number} orbitParams.altitude - 高度
   * @param {number} orbitParams.inclination - 倾角(度)
   * @param {number} orbitParams.raan - 升交点赤经(度)
   * @returns {Array} 轨道点数组 [[x, y, z], ...]
   */
  generateOrbitPoints(orbitParams) {
    const { altitude, inclination, raan } = orbitParams;
    const points = [];
    
    // 生成轨道点
    const segments = 120; // 增加分段数使轨道更平滑
    for (let i = 0; i < segments; i++) {
      const angle = (i / segments) * Math.PI * 2;
      
      // 计算基本位置
      const r = 1 + altitude;
      const x = r * Math.cos(angle);
      const y = r * Math.sin(angle) * Math.cos(inclination * Math.PI / 180);
      const z = r * Math.sin(angle) * Math.sin(inclination * Math.PI / 180);
      
      // 应用升交点赤经旋转
      const raanRad = raan * Math.PI / 180;
      const xRot = x * Math.cos(raanRad) - z * Math.sin(raanRad);
      const zRot = x * Math.sin(raanRad) + z * Math.cos(raanRad);
      
      points.push([xRot, y, zRot]);
    }
    
    // 闭合轨道
    points.push(points[0]);
    return points;
  }
  
  /**
   * 创建轨道线对象
   * @param {number[][]} points - 轨道点数组
   * @param {string} color - 轨道颜色
   * @param {THREE.Scene} scene - three.js场景对象
   * @returns {THREE.Line} 轨道线对象
   */
  createOrbitLine(points: number[][], color: string, scene?: THREE.Object3D): THREE.Line {
    const orbitGeometry = new THREE.BufferGeometry();
    const vertices: number[] = [];
    
    // 将点数组转换为顶点数组
    points.forEach((point: number[]) => {
      vertices.push(point[0], point[1], point[2]);
    });
    
    orbitGeometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
    
    // 创建更明显的轨道线材质
    const orbitMaterial = new THREE.LineBasicMaterial({ 
      color: new THREE.Color(color),
      transparent: true,
      opacity: 0.8, // 调整透明度，使线条清晰但不突兀
      linewidth: 1.5 // 注意：在WebGL中，linewidth可能不会起作用
    });
    
    const orbitLine = new THREE.Line(orbitGeometry, orbitMaterial);
    
    if (scene) {
      scene.add(orbitLine);
    }
    
    return orbitLine;
  }
  
  /**
   * 创建椭圆轨道
   * @param {number} periapsis - 近地点距离
   * @param {number} apoapsis - 远地点距离
   * @param {string} color - 轨道颜色
   * @param {number} inclination - 轨道倾角
   * @returns {Array} 轨道点数组
   */
  createEllipticalOrbit(periapsis, apoapsis, color, inclination) {
    // 椭圆参数
    const semiMajorAxis = (periapsis + apoapsis) / 2;
    const eccentricity = (apoapsis - periapsis) / (apoapsis + periapsis);
    
    const points = [];
    const segments = 128;
    
    for (let i = 0; i <= segments; i++) {
      const theta = (i / segments) * Math.PI * 2;
      
      // 计算基本位置
      const radius = semiMajorAxis * (1 - eccentricity * eccentricity) / (1 + eccentricity * Math.cos(theta));
      const x = radius * Math.cos(theta);
      const y = radius * Math.sin(theta) * Math.cos(inclination * Math.PI / 180);
      const z = radius * Math.sin(theta) * Math.sin(inclination * Math.PI / 180);
      points.push([x, y, z]);
    }
    
    return points;
  }
  
  /**
   * 生成多个预定义轨道并添加到场景
   * @param {Object} orbitPlanes - 轨道面配置对象
   * @param {THREE.Scene} scene - three.js场景对象
   * @param {boolean} visible - 轨道是否可见
   * @returns {Object} 轨道线对象映射
   */
  generateOrbits(orbitPlanes, scene, visible = true) {
    const orbitLines = {};
    
    Object.entries(orbitPlanes).forEach(([planeId, plane]) => {
      // 生成轨道点
      const orbitPoints = this.generateOrbitPoints(plane);
      this.orbitPoints[planeId] = orbitPoints;
      
      // 创建轨道线
      const orbitLine = this.createOrbitLine(orbitPoints, plane.color || this.orbitColors[plane.type], scene);
      orbitLines[planeId] = orbitLine;
      orbitLine.visible = visible;
    });
    
    this.orbitLines = orbitLines;
    return orbitLines;
  }
  
  /**
   * 设置所有轨道的可见性
   * @param {boolean} visible - 是否可见
   */
  setOrbitVisibility(visible) {
    Object.values(this.orbitLines).forEach(line => {
      line.visible = visible;
    });
  }
  
  /**
   * 清除所有轨道
   * @param {THREE.Scene} scene - three.js场景对象
   */
  clearOrbits(scene) {
    Object.values(this.orbitLines).forEach(line => {
      scene.remove(line);
      line.geometry.dispose();
      line.material.dispose();
    });
    
    this.orbitLines = {};
    this.orbitPoints = {};
  }
}